package cc.rengu.igas.bomp.core.realize.impl;

import cc.rengu.igas.bomp.common.constant.BompAppParamConstant;
import cc.rengu.igas.bomp.common.constant.BompTreeNodeConstant;
import cc.rengu.igas.bomp.common.constant.DubboMethodConstant;
import cc.rengu.igas.bomp.common.dao.*;
import cc.rengu.igas.bomp.common.dao.impl.*;
import cc.rengu.igas.bomp.common.entity.*;
import cc.rengu.igas.bomp.common.enums.MchntStatusEnum;
import cc.rengu.igas.bomp.common.enums.RespCodeEnum;
import cc.rengu.igas.bomp.core.realize.MchntVerifyService;
import cc.rengu.igas.bomp.facade.enums.BompSignLicenceTypeEnum;
import cc.rengu.igas.share.common.util.GlobalEsbUtil;
import cc.rengu.igas.smps.facade.base.Header;
import cc.rengu.igas.smps.facade.request.BankAcctInfoQueryRequest;
import cc.rengu.igas.smps.facade.response.BankAcctInfoQueryResponse;
import cc.rengu.igas.smps.facade.result.Result;
import cc.rengu.oltp.service.common.constant.AppParamConstant;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.common.enums.ChannelEnum;
import cc.rengu.oltp.service.model.BizException;
import cc.rengu.oltp.service.realize.DubboService;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.DubboServiceImpl;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.DateUtil;
import cc.rengu.oltp.utility.util.StringUtil;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author: zhangxuran
 * @Date: 2020/4/26 10:12
 * @Description: 商户入驻校验
 */
public class MchntVerifyServiceImpl implements MchntVerifyService {
    private RgLogger rglog = RgLog.getLogger(this.getClass().getName());

    @Override
    public boolean checkMchntBlackInfo(String instId, String mchntNo) throws Exception {
        /*对商户进行黑名单检查*/
        BompMchntBlackListMapper mchntBlackListMapper = new BompMchntBlackListMapperImpl();
        List<MchntBlackListInfo> mchntBlackListInfoList = mchntBlackListMapper.selectBompMchntBlackListInfoByInstIdMchntNo(instId, mchntNo);
        if (!CollectionUtils.isEmpty(mchntBlackListInfoList)) {
            mchntBlackListInfoList = mchntBlackListInfoList.stream().filter(item -> "01".equals(item.getValidStatus())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(mchntBlackListInfoList)) {
                for (MchntBlackListInfo mchntBlackListInfo : mchntBlackListInfoList) {
                    if (mchntBlackListInfo.getValidDate() == null ||
                            DateUtil.compareDate(DateUtil.getCurrentDate(), mchntBlackListInfo.getValidDate()) < 0) {
                        rglog.info("机构:{}的商户{}被列入黑名单。", instId, mchntNo);
                        return true;
                    }
                }
            }
        }

        return false;
    }


    @Override
    public boolean checkMchntBlackInfoByMchntNetworkDomain(String mchntNetworkDomain) throws Exception {
        if (StringUtil.isEmptyOrNull(mchntNetworkDomain)) {
            return false;
        }

        /*对商户进行黑名单检查*/
        BompMchntBlackListMapper mchntBlackListMapper = new BompMchntBlackListMapperImpl();
        List<MchntBlackListInfo> mchntBlackListInfoList = mchntBlackListMapper.selectBompMchntBlackListInfoByMchntNetworkDomain(mchntNetworkDomain);
        if (!CollectionUtils.isEmpty(mchntBlackListInfoList)) {
            mchntBlackListInfoList = mchntBlackListInfoList.stream().filter(item -> "01".equals(item.getValidStatus()) && "01".equals(item.getMchntBlacklistStatus()) && "00".equals(item.getMchntBlacklistType())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(mchntBlackListInfoList)) {
                for (MchntBlackListInfo mchntBlackListInfo : mchntBlackListInfoList) {
                    if (mchntBlackListInfo.getValidDate() == null ||
                            DateUtil.compareDate(DateUtil.getCurrentDate(), mchntBlackListInfo.getValidDate()) < 0) {
                        rglog.info("域名：{}被列入黑名单。", mchntNetworkDomain);
                        return true;
                    }
                }
            }
        }

        return false;
    }


    @Override
    public void verifyLegalMaxByMchntSign(String instId, String artifNo, String artifType) throws Exception {
        MchntSignInfoMapper mchntSignInfoMapper = new MchntSignInfoMapperImpl();
        List<MchntSignInfo> mchntSignInfoList = mchntSignInfoMapper.selectBompMchntSignInfoByArtifId(instId, artifNo, artifType);
        //该法人第一次进行商户入驻 不进行校验
        if (CollectionUtils.isEmpty(mchntSignInfoList)) {
            rglog.debug("该法人第一次进行商户入驻，不校验法人签约上限");
            return;
        }
        rglog.debug("该法人在该机构绑定多个商户，校验法人签约上限");
        //查询表获取法人签约上限
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(instId,
                BompAppParamConstant.MCHNT_PARAM_TYPE, BompAppParamConstant.MAX_SIGN_LEGAL_PERSON);
        //法人机构不配置最大签约上限，则不校验
        if (null == sysParam) {
            rglog.debug("法人机构不配置最大签约上限，不校验");
            return;
        }

        if (mchntSignInfoList.size() > Integer.parseInt(sysParam.getParamValue())) {
            rglog.error("当前商户法人签约已超过上限！不允许再次签约！MAX_NUM:{},CURRENT_NUM:{}",
                    sysParam.getParamValue(), mchntSignInfoList.size());
            throw new BizException(RespCodeEnum.MANAGE_OPERATE_ERROR.getRespCode(), RespCodeEnum.MANAGE_OPERATE_ERROR.getRespDesc());
        }
        rglog.debug("当前机构允许商户法人最大签约数：{},当前法人签约数:{}",
                sysParam.getParamValue(), mchntSignInfoList.size());
    }


    @Override
    public void verifyLicenceMaxByMchntSign(String instId, String mchntNo, String licenceType, String licenceCode) throws Exception {
        if (BompSignLicenceTypeEnum.OTHER.getType().equals(licenceType)) {
            return;
        }
        if (StringUtil.isEmptyOrNull(licenceType) || StringUtil.isEmptyOrNull(licenceCode)) {
            rglog.error("当前商户证件类型<{}>或执照号<{}>为空！不允许签约！！", licenceType, licenceCode);
            throw new BizException(RespCodeEnum.MANAGE_OPERATE_ERROR.getRespCode(), RespCodeEnum.MANAGE_OPERATE_ERROR.getRespDesc());
        }

        MchntSignInfoMapper mchntSignInfoMapper = new MchntSignInfoMapperImpl();
        List<MchntSignInfo> mchntSignInfoList = mchntSignInfoMapper.selectBompMchntSignInfoByLicenceInfo(instId, licenceType, licenceCode);
        if (!CollectionUtils.isEmpty(mchntSignInfoList)) {
            for (int index = mchntSignInfoList.size() - 1; index >= 0; index--) {
                MchntSignInfo mchntSignInfo = mchntSignInfoList.get(index);
                MchntBaseInfoMapper mchntBaseInfoMapper = new MchntBaseInfoMapperImpl();
                MchntBaseInfo orgMchntBaseInfo = mchntBaseInfoMapper.selectMchntBaseInfoByPrimaryKey(mchntSignInfo.getInstId(), mchntSignInfo.getMchntNo());
                if (MchntStatusEnum.CANCEL.getStatus().equals(orgMchntBaseInfo.getMchntStatus())) {
                    rglog.debug("相同签约信息licenceType<{}> licenceCode<{}>商户<{}>状态为已注销,跳过校验.", licenceType, licenceCode, mchntSignInfo.getMchntNo());
                    mchntSignInfoList.remove(index);
                    if (0 != index) {
                        index++;
                    }
                }
            }
        }

        //该法人第一次进行商户入驻 不进行校验
        if (CollectionUtils.isEmpty(mchntSignInfoList)) {
            rglog.debug("该签约证件（营业执照等）第一次进行商户入驻，不校验签约上限");
            return;
        }
        rglog.debug("该签约证件（营业执照等）在该机构绑定多个商户({}),校验法人签约上限", mchntSignInfoList.size());

        //查询表获取行级设置的执照签约上限
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(instId, BompAppParamConstant.MCHNT_PARAM_TYPE, BompAppParamConstant.MAX_SIGN_LICENCE);
        //法人机构不配置执照签约最大上限，则不校验
        if (null == sysParam) {
            rglog.debug("法人机构不配置最大执照签约上限，不校验");
            return;
        }

        //商户原签约信息
        MchntSignInfo orgMchntSignInfo = mchntSignInfoMapper.selectMchntSignInfoByPrimaryKey(instId, mchntNo);
        if (null != orgMchntSignInfo && licenceType.equals(orgMchntSignInfo.getLicenceType()) && licenceCode.equals(orgMchntSignInfo.getLicenceCode())) {
            rglog.debug("商户未修改主要签约信息,不进行校验.");
        } else {
            //新增或修改签约信息,进行校验
            if (mchntSignInfoList.size() > Integer.parseInt(sysParam.getParamValue()) - 1) {
                rglog.error("当前商户执照签约已超过上限！不允许再次签约！MAX_NUM:{},CURRENT_NUM:{}", sysParam.getParamValue(), mchntSignInfoList.size());
                throw new BizException(RespCodeEnum.BUSINESS_LICENSE_REPEAT.getRespCode(), RespCodeEnum.BUSINESS_LICENSE_REPEAT.getRespDesc());
            }
        }
    }

    @Override
    public void verifyAcctInfoMaxByMchntSettle(String instId, String mchntNo, String acctNo) throws Exception {
        if (StringUtil.isEmptyOrNull(acctNo)) {
            rglog.error("当前结算账户为空！不允许进行结算账户管理！！");
            throw new BizException(RespCodeEnum.MANAGE_OPERATE_ERROR.getRespCode(), RespCodeEnum.MANAGE_OPERATE_ERROR.getRespDesc());
        }

        MchntAcctInfoMapper mchntAcctInfoMapper = new MchntAcctInfoMapperImpl();
        List<MchntAcctInfo> mchntAcctInfoList = mchntAcctInfoMapper.selectMchntAcctInfoByAcctNo(instId, acctNo);
        //该法人第一次进行商户入驻 不进行校验
        if (!CollectionUtils.isEmpty(mchntAcctInfoList)) {
            for (int index = mchntAcctInfoList.size() - 1; index >= 0; index--) {
                MchntAcctInfo mchntAcctInfo = mchntAcctInfoList.get(index);
                MchntBaseInfoMapper mchntBaseInfoMapper = new MchntBaseInfoMapperImpl();
                MchntBaseInfo orgMchntBaseInfo = mchntBaseInfoMapper.selectMchntBaseInfoByPrimaryKey(mchntAcctInfo.getInstId(), mchntAcctInfo.getMchntNo());
                if (MchntStatusEnum.CANCEL.getStatus().equals(orgMchntBaseInfo.getMchntStatus())) {
                    rglog.debug("相同结算账户商户<{}>状态为已注销,跳过校验.", mchntAcctInfo.getMchntNo());
                    mchntAcctInfoList.remove(index);
                    if (0 != index) {
                        index++;
                    }
                }
            }
        }
        if (CollectionUtils.isEmpty(mchntAcctInfoList)) {
            rglog.debug("该结算账户第一次进行商户入驻，不校验签约上限");
            return;
        }
        rglog.debug("该结算账户在该机构绑定多个商户({}),校验法人签约上限", mchntAcctInfoList.size());

        //查询表获取行级设置的执照签约上限
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(instId, BompAppParamConstant.MCHNT_PARAM_TYPE, BompAppParamConstant.MAX_SIGN_ACCT_NO);
        //法人机构不配置执照签约最大上限，则不校验
        if (null == sysParam) {
            rglog.debug("法人机构不配置最大账户签约上限，不校验");
            return;
        }

        //商户原结算账户信息
        List<MchntAcctInfo> orgMchntAcctInfoList = mchntAcctInfoMapper.selectMchntAcctInfoByMchntNoAndAcctNo(instId, mchntNo, acctNo);
        if (!CollectionUtils.isEmpty(orgMchntAcctInfoList)) {
            rglog.debug("商户未修改结算账户信息,不进行校验.");
        } else {
            //新增或修改结算账户账号,进行校验
            Map<String, List<MchntAcctInfo>> mchntNoAcctMap = mchntAcctInfoList.stream().collect(Collectors.groupingBy(MchntAcctInfo::getMchntNo));
            if (mchntNoAcctMap.size() > Integer.parseInt(sysParam.getParamValue()) - 1) {
                rglog.error("当前商户结算账户已超过上限！不允许再次签约！MAX_NUM:{},CURRENT_NUM:{}", sysParam.getParamValue(), mchntNoAcctMap.size());
                throw new BizException(RespCodeEnum.ACCT_NO_REPEAT.getRespCode(), RespCodeEnum.ACCT_NO_REPEAT.getRespDesc());
            }
        }
    }

    @Override
    public boolean verifyMchntAllowToD0(MchntBaseInfo mchntBaseInfo) throws Exception {
        rglog.info("校验是否允许D0校验");

        //入驻时间是否超过（包含）N天
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(mchntBaseInfo.getInstId(),
                BompAppParamConstant.MCHNT_PARAM_TYPE, BompAppParamConstant.ALLOW_MCHNT_D0_EXPEND_DAY);

        if (null != sysParam) {
            /*入驻时间格式转换*/
            String mchntExpandTime = DateUtil.dateStringFormatConvert(mchntBaseInfo.getMchntExpandTime(), "yyyy-MM-dd HH:mm:ss.SSS", "yyyyMMdd");
            /*判断入驻时间是否超过（包含）90天 */
            String day = sysParam.getParamValue();
            int num = Integer.parseInt(day);
            int dayNum = DateUtil.compareDate(mchntExpandTime, DateUtil.getFutureDay(-num));
            if (dayNum >= 0) {
                /*商户入驻未超过90天*/
                rglog.error("商户入驻未超过{}天", day);
                return false;
            }
        }

        sysParam = sysParamService.getSysParamInfo(mchntBaseInfo.getInstId(),
                BompAppParamConstant.MCHNT_PARAM_TYPE, BompAppParamConstant.ALLOW_MCHNT_D0_TRANS_DAY);

        if (null != sysParam) {
            String day = sysParam.getParamValue();
            int dayNum = Integer.parseInt(day);
            /*获取商户由当前日期前推30天是有每天有交易*/
            BompMchntAcctSumMapper bompMchntAcctSumMapper = new BompMchntAcctSumMapperImpl();
            List<MchntAcctDetail> mchntTransList = bompMchntAcctSumMapper.selecBompMchntAcctSumByMchntNoAndLimDate(mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo(), DateUtil.getFutureDay(-dayNum), DateUtil.getCurrentDate());
            if (!CollectionUtils.isEmpty(mchntTransList) && mchntTransList.size() >= dayNum) {
                /*商户连续30天有交易*/
                return true;
            } else {
                rglog.error("校验商户连续{}天内有交易不通过", day);
                return false;
            }
        }

        return true;
    }

    @Override
    public boolean verifyMchntAllowToWithdrawal(MchntBaseInfo mchntBaseInfo) throws Exception {
        if (AppParamConstant.YES.equals(mchntBaseInfo.getCashWithdrawalFlag())) {
            rglog.debug("商户已开通提现,不进行提现校验.");
            return true;
        } else {
            rglog.info("校验是否允许提现校验");
            return verifyTransDayAndExpandDay(mchntBaseInfo);
        }
    }

    private boolean verifyTransDayAndExpandDay(MchntBaseInfo mchntBaseInfo) throws Exception {
        //入驻时间是否超过（包含）N天
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(mchntBaseInfo.getInstId(),
                BompAppParamConstant.MCHNT_PARAM_TYPE, BompAppParamConstant.ALLOW_MCHNT_D0_EXPEND_DAY);

        if (null != sysParam && !"0".equals(sysParam.getParamValue())) {
            /*入驻时间格式转换*/
            String mchntExpandTime = DateUtil.dateStringFormatConvert(mchntBaseInfo.getMchntExpandTime(), "yyyy-MM-dd HH:mm:ss.SSS", "yyyyMMdd");
            /*判断入驻时间是否超过（包含）90天 */
            String day = sysParam.getParamValue();
            int num = Integer.parseInt(day);
            int dayNum = DateUtil.compareDate(mchntExpandTime, DateUtil.getFutureDay(-num));
            if (dayNum > 0) {
                /*商户入驻未超过90天*/
                rglog.error("商户入驻未超过{}天", day);
                return false;
            }
        }

        sysParam = sysParamService.getSysParamInfo(mchntBaseInfo.getInstId(),
                BompAppParamConstant.MCHNT_PARAM_TYPE, BompAppParamConstant.ALLOW_MCHNT_D0_TRANS_DAY);

        if (null != sysParam && !"0".equals(sysParam.getParamValue())) {
            String day = sysParam.getParamValue();
            int dayNum = Integer.parseInt(day);
            /*获取商户由当前日期前推30天是有每天有交易*/
            BompMchntAcctSumMapper bompMchntAcctSumMapper = new BompMchntAcctSumMapperImpl();
            List<MchntAcctDetail> mchntTransList = bompMchntAcctSumMapper.selecBompMchntAcctSumByMchntNoAndLimDate(mchntBaseInfo.getInstId(), mchntBaseInfo.getMchntNo(), DateUtil.getFutureDay(-dayNum), DateUtil.getCurrentDate());
            if (!CollectionUtils.isEmpty(mchntTransList) && mchntTransList.size() >= dayNum) {
                /*商户连续30天有交易*/
                return true;
            } else {
                rglog.error("校验商户连续{}天内有交易不通过", day);
                return false;
            }
        }

        return true;
    }

    //region 六要素
    @Override
    public boolean verifySixElement(String instId, String mchntNo, String oprType) throws Exception {
        if (StringUtil.isEmptyOrNull(instId) || StringUtil.isEmptyOrNull(mchntNo) || StringUtil.isEmptyOrNull(oprType)) {
            rglog.error("传参缺失,校验不通过.");
            return false;
        }
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String licenceType = xmlTreeUtil.getXmlTreeStringValue(BompTreeNodeConstant.LICENCE_TYPE);
        String licenceCode = xmlTreeUtil.getXmlTreeStringValue(BompTreeNodeConstant.LICENCE_CODE);
        String certType = xmlTreeUtil.getXmlTreeStringValue(BompTreeNodeConstant.CERT_TYPE);
        String certNo = xmlTreeUtil.getXmlTreeStringValue(BompTreeNodeConstant.CERT_NO);
        String mobile = xmlTreeUtil.getXmlTreeStringValue(BompTreeNodeConstant.MOBILE);
        String settleAcctNo = xmlTreeUtil.getXmlTreeStringValue(BompTreeNodeConstant.SETTLE_ACCT_NO);

        switch (oprType) {
            //011-新增签约信息
            //012-新增结算信息
            //021-修改签约信息
            //022-修改结算信息
            case "011":
                break;
            case "012":
            case "022":
                return checkSettleAcctNo(instId, mchntNo, settleAcctNo);
            case "021":
                return checkSignInfo(instId, mchntNo, licenceType, licenceCode, certType, certNo, mobile);
            default:
                rglog.error("此操作类型<{}>不需要进行六要素校验.", oprType);
                return true;
        }
        return true;
    }

    /*查询签约信息相同的商户,判断其结算账号是否与本商户结算账号相同,相同则六要素校验不通过*/
    private boolean checkSignInfo(String instId, String mchntNo, String licenceType, String licenceCode, String certType, String certNo, String mobile) throws Exception {
        MchntSignInfoMapper mchntSignInfoMapper = new MchntSignInfoMapperImpl();
        MchntAcctInfoMapper mchntAcctInfoMapper = new MchntAcctInfoMapperImpl();

        //根据五要素查签约信息列表
        List<MchntSignInfo> mchntSignInfoList = mchntSignInfoMapper.selectBompMchntSignInfoByLicenceAndCertAndMobile(instId, licenceType, licenceCode, certType, certNo, mobile);
        if (CollectionUtils.isEmpty(mchntSignInfoList)) {
            rglog.debug("五要素不重复,六要素肯定不重复,校验通过.");
            return true;
        }

        //查询本商户结算账户信息
        List<MchntAcctInfo> mchntAcctInfoList = mchntAcctInfoMapper.selectMchntAcctInfoByMchntNo(instId, mchntNo);
        if (CollectionUtils.isEmpty(mchntAcctInfoList)) {
            rglog.debug("本商户无结算账户信息.");
            return true;
        }

        for (MchntSignInfo orgMchntSignInfo : mchntSignInfoList) {
            //原商户号
            String orgMchntNo = orgMchntSignInfo.getMchntNo();
            if (mchntNo.equals(orgMchntNo)) {
                rglog.debug("本商户信息.");
                continue;
            }

            MchntBaseInfoMapper mchntBaseInfoMapper = new MchntBaseInfoMapperImpl();
            MchntBaseInfo orgMchntBaseInfo = mchntBaseInfoMapper.selectMchntBaseInfoByPrimaryKey(orgMchntSignInfo.getInstId(), orgMchntSignInfo.getMchntNo());
            if (MchntStatusEnum.CANCEL.getStatus().equals(orgMchntBaseInfo.getMchntStatus())) {
                rglog.debug("相同结算账户商户<{}>状态为已注销,跳过校验.", orgMchntSignInfo.getMchntNo());
                continue;
            }

            //原商户结算账户信息列表
            List<MchntAcctInfo> orgMchntAcctInfoList = mchntAcctInfoMapper.selectMchntAcctInfoByMchntNo(instId, orgMchntNo);
            if (CollectionUtils.isEmpty(orgMchntAcctInfoList)) {
                rglog.debug("原商户无结算账户信息.");
                continue;
            }

            for (MchntAcctInfo orgMchntAcctInfo : orgMchntAcctInfoList) {
                String orgSettleAcctNo = orgMchntAcctInfo.getSettleAcctNo();
                for (MchntAcctInfo mchntAcctInfo : mchntAcctInfoList) {
                    if (mchntAcctInfo.getSettleAcctNo().equals(orgSettleAcctNo)) {
                        //五要素相同,结算账户也相同,六要素相加,都在同一个商户
                        rglog.error("六要素校验不通过.");
                        return false;
                    }
                }
            }
        }
        rglog.debug("六要素校验通过.");
        return true;
    }

    /*查结算账户相同的商户,判断其签约信息是否与本商户相同,相同则校验不通过*/
    private boolean checkSettleAcctNo(String instId, String mchntNo, String settleAcctNo) throws Exception {
        MchntSignInfoMapper mchntSignInfoMapper = new MchntSignInfoMapperImpl();
        MchntAcctInfoMapper mchntAcctInfoMapper = new MchntAcctInfoMapperImpl();

        List<MchntAcctInfo> mchntAcctInfoList = mchntAcctInfoMapper.selectMchntAcctInfoByAcctNo(instId, settleAcctNo);
        if (CollectionUtils.isEmpty(mchntAcctInfoList)) {
            rglog.debug("结算账号第一次绑定,校验通过.");
            return true;
        }
        //查询本商户的签约信息
        MchntSignInfo mchntSignInfo = mchntSignInfoMapper.selectMchntSignInfoByPrimaryKey(instId, mchntNo);
        if (null == mchntSignInfo) {
            rglog.error("未查询到本商户签约信息.");
            return true;
        }
        String licenceType = mchntSignInfo.getLicenceType();
        String licenceCode = mchntSignInfo.getLicenceCode();
        String certType = mchntSignInfo.getArtifCertType();
        String certNo = mchntSignInfo.getArtifCertNo();
        String mobile = mchntSignInfo.getArtifMobile();

        for (MchntAcctInfo mchntAcctInfo : mchntAcctInfoList) {
            String orgMchntNo = mchntAcctInfo.getMchntNo();
            if (mchntNo.equals(orgMchntNo)) {
                rglog.debug("本商户信息.");
                continue;
            }

            MchntBaseInfoMapper mchntBaseInfoMapper = new MchntBaseInfoMapperImpl();
            MchntBaseInfo orgMchntBaseInfo = mchntBaseInfoMapper.selectMchntBaseInfoByPrimaryKey(mchntAcctInfo.getInstId(), mchntAcctInfo.getMchntNo());
            if (MchntStatusEnum.CANCEL.getStatus().equals(orgMchntBaseInfo.getMchntStatus())) {
                rglog.debug("相同结算账户商户<{}>状态为已注销,跳过校验.", mchntAcctInfo.getMchntNo());
                continue;
            }

            MchntSignInfo orgMchntSignInfo = mchntSignInfoMapper.selectMchntSignInfoByPrimaryKey(instId, orgMchntNo);
            if (null == orgMchntSignInfo) {
                rglog.debug("原商户无签约信息.");
                continue;
            }

            String orgLicenceType = orgMchntSignInfo.getLicenceType();
            String orgLicenceCode = orgMchntSignInfo.getLicenceCode();
            String orgCertType = orgMchntSignInfo.getArtifCertType();
            String orgCertNo = orgMchntSignInfo.getArtifCertNo();
            String orgMobile = orgMchntSignInfo.getArtifMobile();

            if (licenceType.equals(orgLicenceType) && licenceCode.equals(orgLicenceCode)
                    && certType.equals(orgCertType) && certNo.equals(orgCertNo)
                    && mobile.equals(orgMobile)) {
                //签约账号相同,剩余五要素也相同,六要素相加，都在同一个商户
                rglog.error("六要素校验不通过.");
                return false;
            }
        }
        rglog.debug("六要素校验通过.");
        return true;
    }
    //endregion

    @Override
    public boolean verifyCorporateAccount(String instId, String mchntNo, String acctNo) throws Exception {
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        MchntSignInfo mchntSignInfo = (MchntSignInfo) xmlTreeUtil.getXmlTreeObjectValue(BompTreeNodeConstant.MCHNT_SIGN_INFO, MchntSignInfo.class);
        if (null == mchntSignInfo) {
            MchntSignInfoMapper mchntSignInfoMapper = new MchntSignInfoMapperImpl();
            mchntSignInfo = mchntSignInfoMapper.selectMchntSignInfoByPrimaryKey(instId, mchntNo);
            if (null == mchntSignInfo) {
                rglog.debug("商户无签约信息,不进行结算账号对公户校验.");
                return true;
            }
        }
        if (!BompSignLicenceTypeEnum.BUSINESS_LICENSE.getType().equals(mchntSignInfo.getLicenceType())) {
            rglog.debug("商户签约类型非营业执照,不进行校验.");
            return true;
        }

        /*获取核心客户号*/
        BankAcctInfoQueryRequest coreAcctInfoQueryRequest = new BankAcctInfoQueryRequest();
        Header acctInfoHeader = new Header();
        acctInfoHeader.setInstId(instId);
        acctInfoHeader.setSrcSysId(AppParamConstant.SYS_ID);
        acctInfoHeader.setChanlId(ChannelEnum.BSPS.getChannelType());
        acctInfoHeader.setTransDate(DateUtil.getCurrentDate());
        acctInfoHeader.setTransTime(DateUtil.getCurrentTime());
        acctInfoHeader.setVersion("1.0.0");
        acctInfoHeader.setBizType("00");
        acctInfoHeader.setTxnNum("00010000200000");
        acctInfoHeader.setTraceNo(GlobalEsbUtil.generateEsbSeqeuenceNumber(instId));
        coreAcctInfoQueryRequest.setAcctNo(acctNo);
        coreAcctInfoQueryRequest.setHeader(acctInfoHeader);
        DubboService dubboService = new DubboServiceImpl();
        Result<BankAcctInfoQueryResponse> result = (Result<BankAcctInfoQueryResponse>) dubboService.callDubboService(DubboMethodConstant.DUBBO_BANK_SUP_SERVICE, "bankAcctInfoQuery", coreAcctInfoQueryRequest);
        if (null == result || null == result.getResult()) {
            rglog.error("调用通道查询账户信息失败");
            throw new BizException(RespCodeEnum.SYSTEM_ERROR.getRespCode(), RespCodeEnum.SYSTEM_ERROR.getRespDesc());
        } else if (!result.isSuccess() || !DubboMethodConstant.DUBBO_SUCCESS.equals(result.getResult().getRespCode())) {
            rglog.error("调用通道查询账户信息失败");
            throw new BizException(result.getResult().getRespCode(), result.getResult().getRespDesc());
        }

        //交易成功 得到核心客户号
        BankAcctInfoQueryResponse coreAcctInfoQueryResponse = result.getResult();
        //通道新增接口后修改请求、响应对象和Dubbo方法名即可
        //TODO 调用核心 查询本行对公户

        return true;
    }

    @Override
    public boolean checkMchntBlackInfoByLegalInfo(String artifCertType, String artifCertNo) throws Exception {
        if (StringUtil.isEmptyOrNull(artifCertNo)) {
            return false;
        }

        /*对法人进行黑名单检查*/
        BompMchntBlackListMapper mchntBlackListMapper = new BompMchntBlackListMapperImpl();
        List<MchntBlackListInfo> mchntBlackListInfoList = mchntBlackListMapper.selectBompMchntBlackListInfoByArtifCertNo(artifCertType, artifCertNo);
        if (!CollectionUtils.isEmpty(mchntBlackListInfoList)) {
            mchntBlackListInfoList = mchntBlackListInfoList.stream().filter(item -> "01".equals(item.getValidStatus()) && "01".equals(item.getMchntBlacklistStatus()) && "00".equals(item.getMchntBlacklistType())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(mchntBlackListInfoList)) {
                for (MchntBlackListInfo mchntBlackListInfo : mchntBlackListInfoList) {
                    if (mchntBlackListInfo.getValidDate() == null ||
                            DateUtil.compareDate(DateUtil.getCurrentDate(), mchntBlackListInfo.getValidDate()) < 0) {
                        rglog.info("法人证件号：{}被列入黑名单。", artifCertNo);
                        return true;
                    }
                }
            }
        }

        return false;
    }


    @Override
    public boolean checkMchntBlackInfoByLicenceCode(String licenceCode) throws Exception {
        if (StringUtil.isEmptyOrNull(licenceCode)) {
            return false;
        }

        /*对法人进行黑名单检查*/
        BompMchntBlackListMapper mchntBlackListMapper = new BompMchntBlackListMapperImpl();
        List<MchntBlackListInfo> mchntBlackListInfoList = mchntBlackListMapper.selectBompMchntBlackListInfoByLicenceCode(licenceCode);
        if (!CollectionUtils.isEmpty(mchntBlackListInfoList)) {
            mchntBlackListInfoList = mchntBlackListInfoList.stream().filter(item -> "01".equals(item.getValidStatus()) && "01".equals(item.getMchntBlacklistStatus()) && "00".equals(item.getMchntBlacklistType())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(mchntBlackListInfoList)) {
                for (MchntBlackListInfo mchntBlackListInfo : mchntBlackListInfoList) {
                    if (mchntBlackListInfo.getValidDate() == null ||
                            DateUtil.compareDate(DateUtil.getCurrentDate(), mchntBlackListInfo.getValidDate()) < 0) {
                        rglog.info("商户证件号licenceCode：{}被列入黑名单。", licenceCode);
                        return true;
                    }
                }
            }
        }

        return false;
    }
}
